package com.sa35.fbs.dao.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * This is a utility class to provide some help or work around related to SQL
 * issues
 */
public final class SqlUtil {

	/**
	 * SQL "IN" clause is limited to 1000 parameters only. Thus separate it per
	 * 1000 per array and execute the query repeatedly per 1000 data.
	 * 
	 * @param dataSet
	 *            A set of data to be separated to per 1000 data
	 * @return A list of sets with maximum 1000 data per set
	 */
	public static List<Set<Long>> oneThousandSeparationForSqlINClause(Set<Long> dataSet) {
		List<Set<Long>> separatedDataSetList = new ArrayList<Set<Long>>(1);

		if (dataSet != null) {
			if (!dataSet.isEmpty()) {
				if (dataSet.size() > 1000) {
					int x = 0;
					int idx = 1;
					Set<Long> separatedDataSet = new HashSet<Long>(1000);
					for (Long theId : dataSet) {
						if (x < 1000) {
							separatedDataSet.add(theId);
							x++;
						} else {
							separatedDataSetList.add(separatedDataSet);

							if (dataSet.size() - idx > 1000) {
								separatedDataSet = new HashSet<Long>(1000);
							} else {
								separatedDataSet = new HashSet<Long>(dataSet.size() - idx);
							}
							x = 0;
						}
						idx++;
					}
				} else {
					separatedDataSetList.add(dataSet);
				}

			}
		}

		return separatedDataSetList;
	}

	/**
	 * SQL "IN" clause is limited to 1000 parameters only. Thus separate it per
	 * 1000 per array and execute the query repeatedly per 1000 data.
	 * 
	 * @param dataSet
	 *            A set of data to be separated to per 1000 data
	 * @return A list of sets with maximum 1000 data per set
	 */
	public static List<List<Long>> oneThousandSeparationForSqlINClause(List<Long> dataSet) {
		List<List<Long>> separatedDataSetList = new ArrayList<List<Long>>(1);

		if (dataSet == null || dataSet.isEmpty()) {
			return separatedDataSetList;
		} 

		if (dataSet.size() > 1000) {
			int x = 0;
			int idx = 1;
			List<Long> separatedDataSet = new ArrayList<Long>(1000);
			for (Long theId : dataSet) {
				if (x < 1000) {
					separatedDataSet.add(theId);
					x++;
				} else {
					separatedDataSetList.add(separatedDataSet);

					if (dataSet.size() - idx > 1000) {
						separatedDataSet = new ArrayList<Long>(1000);
					} else {
						separatedDataSet = new ArrayList<Long>(dataSet.size() - idx);
					}
					x = 0;
				}
				idx++;
			}
		} else {
			separatedDataSetList.add(dataSet);
		}

		return separatedDataSetList;
	}

	private SqlUtil() {
	}

}
